package com.code2roc.fastboot.system.common.controller;

import com.code2roc.fastboot.framework.file.LocalFileStoargeProperty;
import com.code2roc.fastboot.system.common.bizlogic.AttachLogic;
import com.code2roc.fastboot.system.common.model.SystemAttachDO;
import com.code2roc.fastboot.system.common.service.ISystemAttachService;
import com.code2roc.fastboot.model.BaseBootController;
import com.code2roc.fastboot.framework.model.Result;
import com.code2roc.fastboot.framework.util.ConvertOp;
import com.code2roc.fastboot.framework.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/system/common/attach")
public class SystemAttachController extends BaseBootController {
    @Autowired
    private ISystemAttachService attachService;
    @Autowired
    private AttachLogic attachLogic;

    @PostMapping("/list")
    @ResponseBody
    public Object list(@RequestBody Map<String, Object> params) throws Exception {
        String group_guid = ConvertOp.convert2String(params.get("group_guid"));
        String group_type = ConvertOp.convert2String(params.get("group_type"));
        if (StringUtil.isEmpty(group_type)) {
            group_type = "default";
        }
        if (StringUtil.isEmpty(group_guid)) {
            return Result.errorResult().setMsg("附件分组guid不能为空");
        }
        List<SystemAttachDO> attachmentList = attachService.selectListByGroupGuid(group_guid, group_type);
        return Result.okResult().add("obj", attachmentList);
    }

    @PostMapping("/manageList")
    @ResponseBody
    public Object manageList(@RequestBody Map<String, Object> params) throws Exception {
        Result result = Result.okResult();
        String attach_name = ConvertOp.convert2String(params.get("attach_name"));
        String group_guid = ConvertOp.convert2String(params.get("group_guid"));
        String group_type = ConvertOp.convert2String(params.get("group_type"));
        HashMap paramMap = new HashMap();
        String sql = "1=1";
        if (!StringUtil.isEmpty(attach_name)) {
            sql += " and attach_name like #{attach_name}";
            paramMap.put("attach_name", "%" + attach_name + "%");
        }
        if (!StringUtil.isEmpty(group_guid)) {
            sql += " and group_guid= #{group_guid}";
            paramMap.put("group_guid", group_guid);
        }
        if (!StringUtil.isEmpty(group_type)) {
            sql += " and group_type= #{group_type}";
            paramMap.put("group_type", group_type);
        }
        List<SystemAttachDO> rows = attachService.selectPageList("*", sql, "gmt_create desc", paramMap);
        int total = attachService.selectCount(sql, paramMap);
        result.add("rows", rows);
        result.add("total", total);
        return result;
    }

    @PostMapping("/upload")
    @ResponseBody
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.READ_UNCOMMITTED)
    public Object upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception {
        //获取文件名
        String attach_name = file.getOriginalFilename();
        //获取文件大小
        long attach_size = file.getSize();
        //获取文件分组guid
        String group_guid = request.getParameter("group_guid");
        //获取文件分组type
        String group_type = request.getParameter("group_type");
        if (StringUtil.isEmpty(group_guid)) {
            return Result.errorResult().setMsg("附件分组guid不能为空");
        }
        if (StringUtil.isEmpty(group_type)) {
            group_type = "default";
        }
        attachLogic.uploadAttach(attach_name, attach_size, group_guid, group_type, file.getInputStream());
        return Result.okResult();
    }

    @PostMapping("/uploadChunkFile")
    @ResponseBody
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.READ_UNCOMMITTED)
    public Object uploadChunkFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception {
        //获取文件名
        String attach_name = file.getOriginalFilename();
        //获取文件分组guid
        String group_guid = request.getParameter("group_guid");
        //获取文件分组type
        String group_type = request.getParameter("group_type");
        //预生成附件主键
        String attachGuid = request.getParameter("attachGuid");
        //分片数量
        int chunkCount = ConvertOp.convert2Int(request.getParameter("chunkCount"));
        //分片下标
        int chunkIndex = ConvertOp.convert2Int(request.getParameter("chunkIndex"));
        //分片大小
        int chunkSize = ConvertOp.convert2Int(request.getParameter("chunkSize"));
        //文件校验
        String fileMD5 = request.getParameter("fileMD5");
        if (StringUtil.isEmpty(group_guid)) {
            return Result.errorResult().setMsg("附件分组guid不能为空");
        }
        if (StringUtil.isEmpty(group_type)) {
            group_type = "default";
        }
        attachLogic.uploadChunkAttach(attachGuid,attach_name,group_guid, group_type, fileMD5,chunkCount, chunkIndex, chunkSize,file.getInputStream());
        return Result.okResult();
    }


    @PostMapping("/delete")
    @ResponseBody
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.READ_UNCOMMITTED)
    public Object delete(@RequestBody Map<String, Object> params) throws Exception {
        String row_id = ConvertOp.convert2String(params.get("row_id"));
        attachLogic.deleteAttach(row_id);
        return Result.okResult();
    }

    @GetMapping("/download")
    @ResponseBody
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.READ_UNCOMMITTED)
    public Object download(@RequestParam("row_id") String row_id, HttpServletResponse response) throws Exception {
        if (StringUtil.isEmpty(row_id)) {
            return Result.errorResult().setMsg("文件不存在");
        }
        String fileUrl = attachLogic.getAttachUrl(row_id);
        response.sendRedirect(fileUrl);
        return "";
    }

    @GetMapping("/downLocal")
    @ResponseBody
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.READ_UNCOMMITTED)
    public Object downLocal(@RequestParam("row_id") String row_id, HttpServletResponse response) throws Exception {
        if (StringUtil.isEmpty(row_id)) {
            return Result.errorResult().setMsg("文件不存在");
        }
        SystemAttachDO attachDO = attachService.selectOne(row_id);
        LocalFileStoargeProperty property = (LocalFileStoargeProperty)attachLogic.getFileStoargeProperty();
        String filePath = property.getLocalFilePath() + attachDO.getAttach_virtual_path();
        File file = new File(filePath);
        if (!file.exists()) {
            return "文件不存在！";
        }
        String filetype = attachDO.getAttach_type().toLowerCase();
        String filename = attachDO.getAttach_name();
        if (filetype.equals("png") || filetype.equals("jpg") || filetype.equals("jpeg")) {
            response.setContentType("image/" + filetype);
            response.setHeader("Content-Disposition", "filename=" + URLEncoder.encode(filename, "utf-8"));
        } else if ("pdf".equals(filetype)) {
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "filename=" + URLEncoder.encode(filename, "utf-8"));
        } else {
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));
        }
        response.setCharacterEncoding("utf-8");
        response.setContentLength((int) file.length());

        byte[] buff = new byte[(int) file.length()];
        BufferedInputStream bufferedInputStream = null;
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
            int i = 0;
            while ((i = bufferedInputStream.read(buff)) != -1) {
                outputStream.write(buff, 0, i);
                outputStream.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            try {
                bufferedInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    @GetMapping("/readExportXmlFile")
    @ResponseBody
    public String readExportXmlFile(@RequestParam("fileid") String fileid, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String configPath = "tempfiles/export/";
        String filePath = configPath + fileid + ".xml";
        File file = new File(filePath);
        if (!file.exists()) {
            return "文件不存在！";
        }
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileid + ".xml", "utf-8"));
        response.setCharacterEncoding("utf-8");
        response.setContentLength((int) file.length());

        byte[] buff = new byte[(int) file.length()];
        BufferedInputStream bufferedInputStream = null;
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
            int i = 0;
            while ((i = bufferedInputStream.read(buff)) != -1) {
                outputStream.write(buff, 0, i);
                outputStream.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            try {
                bufferedInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }
}
